package com.wyw.base.comm;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import com.wyw.base.util.BaseUtil;
import com.wyw.base.util.WebUtil;
import com.wyw.core.exception.WYWIllegalException;
import com.wyw.core.secu.dto.UserDetailInfo;
import com.wyw.core.secu.support.SecuUtil;
import com.wyw.core.util.CacheManager;
import com.wyw.core.util.WebCacheManager;
import com.wyw.core.web.servelet.JsonModel;
import com.wyw.core.web.servelet.RegClassType;
import com.wyw.core.web.servelet.TaskListQuery;
import com.wyw.core.web.servelet.TaskListQueryResult;
import com.wyw.core.workflow.WorkflowConstant;
import com.wyw.core.workflow.dto.processdef.ActivityDto;
import com.wyw.core.workflow.dto.processdef.ProcessDefinitionDto;
import com.wyw.core.workflow.service.WorkflowService;
import com.wyw.core.workflow.service.support.WorkFlowTask;


@Controller 
public class WorkFlow {
	protected final Log logger = LogFactory.getLog(getClass());
	
	
	@Autowired
	private WorkflowService workflowService;
	
	@RequestMapping(value = "/workFlow/queryTaskListResult.biz",method=RequestMethod.POST)
	public @ResponseBody JsonModel queryTaskListResult(HttpServletRequest request)throws Exception{
			Map dataMap= bondRequest(request);
			TaskListQuery taskListQuery=(TaskListQuery)dataMap.get("_taskListQuery");
			TaskListQueryResult taskListQueryResult;
			UserDetailInfo userDetails=WebUtil.getCurrentUserDetail();
			String bizTypeCode = (String)dataMap.get("_bizTypeCode");
			Map queryMap=(Map)dataMap.get("query");
			String taskQueryType=(String)queryMap.get("taskQueryType");
			
			//缓存中列表查询唯一键userId.bizTypeCode.taskListQueryResult.taskQueryType
			String cacheKey=userDetails.getUsername()+"."+bizTypeCode+".taskListQueryResult."+taskQueryType;
			String queryCacheKey=(String)dataMap.get("_queryCacheKey");
			TaskListQueryResult taskListQueryResultShow;
			JsonModel jsonModel = new JsonModel();
			if(taskListQuery.getButtonQuery() || (BaseUtil.isEmpty(queryCacheKey) && !taskListQuery.getButtonQuery())){//点击查询
				BaseUtil.descObject("数据库查询");
				queryMap.put("bizTypeCode", bizTypeCode);
				taskListQueryResult =workflowService.queryTaskListResult(userDetails, bizTypeCode,queryMap);
				taskListQueryResult.setPage(taskListQuery.getPage());
				
				WebCacheManager.put(cacheKey, taskListQueryResult);
				taskListQueryResultShow= getShowTaskListResult(taskListQuery, taskListQueryResult);
				jsonModel.addAttribute("result", taskListQueryResultShow);
				jsonModel.addAttribute("queryCacheKey", cacheKey);
				 return jsonModel;
			}else{//控件自身查询
				BaseUtil.descObject("cache中查询:queryCacheKey:",queryCacheKey);
				Object result=WebCacheManager.get(queryCacheKey);
				if(result !=null){//cache中有记录
					taskListQueryResult = (TaskListQueryResult)result;
					if(BaseUtil.isNotEmpty(taskListQuery.getSort())){//要求排序
						List taskList=taskListQueryResult.getRows();
						if(taskList !=null && taskList.size()>0){
							taskList=BaseUtil.sortMapList(taskListQueryResult.getRows(), taskListQuery.getSort(), taskListQuery.getOrder());
							taskListQueryResult.setRows(taskList);
						}
					}
					taskListQueryResultShow= getShowTaskListResult(taskListQuery, taskListQueryResult);
					return new JsonModel("result",taskListQueryResultShow);
				}else{
					return new JsonModel("result",new TaskListQueryResult());
				}
			}
	}
	
	private TaskListQueryResult getShowTaskListResult(TaskListQuery taskListQuery,TaskListQueryResult taskListQueryResult){
		if(taskListQueryResult.getRows()==null || taskListQueryResult.getRows().size() < taskListQuery.getRows()){
			return taskListQueryResult;
		}else{
			TaskListQueryResult taskListQueryResultShow= new TaskListQueryResult();
			taskListQueryResultShow.setPage(taskListQuery.getPage());
			taskListQueryResultShow.setTotal(taskListQueryResult.getTotal());
			List listShow = new ArrayList();
			int begin=(taskListQuery.getPage()-1) *taskListQuery.getRows();
			int end=taskListQuery.getPage() * taskListQuery.getRows() ;
			end = end > taskListQueryResult.getTotal()?taskListQueryResult.getTotal():end;
			for(int i=begin;i<end;i++){
				listShow.add(taskListQueryResult.getRows().get(i));
			}
			taskListQueryResultShow.setRows(listShow);
			return taskListQueryResultShow;
		}
	}
	
	//单个参数的获取,任务列表入口
	@RequestMapping(value = "/workFlow/queryTaskList.biz",method=RequestMethod.POST)
	public String queryTaskList(@ModelAttribute("bizTypeCode") String bizTypeCode,Map model)throws WYWIllegalException{
		if(StringUtils.isEmpty(bizTypeCode)){
			throw new WYWIllegalException("非法操作，无此业务");
		}
		workflowService.queryTaskList(WebUtil.getCurrentUserDetail(), bizTypeCode, model);
		String viewName =(String)model.get(WorkflowService.task_list_view_name);
		return viewName;
	}
	
	
	//单个参数的获取
	@RequestMapping(value = "/workFlow/creatNewProcessRedirect.biz",method=RequestMethod.POST)
	public ModelAndView   creatNewProcessRedirect(@ModelAttribute("bizTypeCode") String bizTypeCode,Model model)throws WYWIllegalException{
		if(StringUtils.isEmpty(bizTypeCode)){
			throw new WYWIllegalException("非法操作，无此业务");
		}
		Map processDefinitionMap=(Map) CacheManager.get(CacheManager.process_definition_map);
		ProcessDefinitionDto processDefinitionDto=(ProcessDefinitionDto)processDefinitionMap.get(bizTypeCode);
		
		UserDetailInfo userDetails=WebUtil.getCurrentUserDetail();
		if(SecuUtil.checkUserHasAuthentication(userDetails, processDefinitionDto.getStartRole())){
			if(processDefinitionDto.getStartStrategic().equals(WorkflowConstant.wf_start_strategic_direct)){
				String taskId =workflowService.startProcessByHumanActivityWithView(userDetails, bizTypeCode,model);
				model.addAttribute("taskId",taskId);
				ModelAndView modelAndView = new ModelAndView(new RedirectView("queryTaskHandleInfo.biz"),model.asMap());
				return modelAndView ;//"redirect:queryTaskHandleInfo.biz";
			}else{
				throw new WYWIllegalException("非法操作，无此业务");
			}								
		}else{
			throw new WYWIllegalException("非法操作，无此业务");
		}
	}
			
	
	//单个参数的获取
		@RequestMapping(value = "/workFlow/creatNewProcess.biz",method=RequestMethod.POST ,produces={MediaType.APPLICATION_JSON_VALUE})
		@ResponseBody 
		public JsonModel creatNewProcess(@RequestBody  WorkFlowTask workFlowTask,Model model)throws WYWIllegalException{
			if(StringUtils.isEmpty(workFlowTask.getBizTypeCode())){
				throw new WYWIllegalException("非法操作，无此业务");
			}
			Map processDefinitionMap=(Map) CacheManager.get(CacheManager.process_definition_map);
			ProcessDefinitionDto processDefinitionDto=(ProcessDefinitionDto)processDefinitionMap.get(workFlowTask.getBizTypeCode());
			UserDetailInfo userDetails=WebUtil.getCurrentUserDetail();
			if(SecuUtil.checkUserHasAuthentication(userDetails, processDefinitionDto.getStartRole())){
				if(processDefinitionDto.getStartStrategic().equals(WorkflowConstant.wf_start_strategic_direct)){
					String taskId =workflowService.startProcessByHumanActivity(userDetails, workFlowTask.getBizTypeCode());
					//String taskId="3508";
					JsonModel jsonModel = new JsonModel("taskId",taskId);
					logger.info(jsonModel);
					return  jsonModel;
				}else{
					throw new WYWIllegalException("非法操作，无此业务");
				}								
			}else{
				throw new WYWIllegalException("非法操作，无此业务");
			}
		}
		
		@RequestMapping(value = "/workFlow/loadTask.biz",method=RequestMethod.POST)
		public String loadTask(@ModelAttribute("taskId")String taskId,Map model)throws WYWIllegalException{
			logger.info("taskId1:"+taskId);
			workflowService.loadTask(WebUtil.getCurrentUserDetail(), taskId, model);
			ActivityDto activityDto = (ActivityDto)model.get(WorkflowConstant.work_flow_task_def);
			return activityDto.getHandleView();
		}
		
		
		
		@RequestMapping(value = "/workFlow/completeTask.biz",method=RequestMethod.POST ,produces={MediaType.APPLICATION_JSON_VALUE})
		public @ResponseBody JsonModel completeTask(HttpServletRequest request)throws Exception{
			try{
			Map dataMap= bondRequest( request);
			workflowService.completeTask(WebUtil.getCurrentUserDetail(),dataMap);
			JsonModel jsonModel = new JsonModel("allRegistData",dataMap);
			return  jsonModel;
			}catch(Exception e){
				logger.debug(e);
				return new JsonModel(false,e.getMessage());
			}
		}
		
		
		
		
		
		
		private String getRequestToString(HttpServletRequest request)throws Exception{
			InputStream inputStream = request.getInputStream();
			String in="";
			if(inputStream !=null){
				BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));
				StringBuilder stringBuilder = new StringBuilder();
				char[] charBuffer = new char[128];
				int bytesRead=-1;
				while( (bytesRead =bufferedReader.read(charBuffer)) >0){
					stringBuilder.append(charBuffer,0,bytesRead);
				}
				
				in=stringBuilder.toString();
				logger.info("json String values:"+in);
				bufferedReader.close();
				
				//还不知道要不要 inputStream.close();
			}
			return in;
		}
		
		private Map bondRequest(HttpServletRequest request)throws Exception{
			String content=getRequestToString( request);
			ObjectMapper objectMapper =new ObjectMapper();
			JsonNode jsonNode = objectMapper.readTree(content);
			RegClassType [] regClassTypes;
			try{
				regClassTypes=objectMapper.readValue(jsonNode.get("_regClassType"), RegClassType[].class);
			}catch(Exception e){
				logger.info("regClassTypes 为空.");
				regClassTypes=null;
			}
			
			
			Map dataMap = new HashMap();
			if(regClassTypes !=null){
				for(RegClassType regClassType :regClassTypes){
					Class clazz= Class.forName(regClassType.getClassName());
					if(! regClassType.getIsArray()){
						dataMap.put(regClassType.getKey(), objectMapper.readValue(jsonNode.get(regClassType.getKey()), clazz));
					}else{
						dataMap.put(regClassType.getKey(), objectMapper.readValue(jsonNode.get(regClassType.getKey()), objectMapper.getTypeFactory().constructCollectionType(List.class, clazz)));
					}
				}
			}
			
			logger.debug("allValue++++:"+objectMapper.writeValueAsString(dataMap));
			Iterator iterator = jsonNode.getFieldNames();
			String fieldName ;
			JsonNode jsonNodeIt;
			while(iterator.hasNext()){
				fieldName = (String)iterator.next();
				logger.debug("fieldName:"+fieldName);
				if(! dataMap.containsKey(fieldName) && !fieldName.equals("_regClassType")){
					jsonNodeIt=jsonNode.get(fieldName);
					if(jsonNodeIt.isValueNode()){
						dataMap.put(fieldName, jsonNodeIt.getTextValue());
					}else if(jsonNodeIt.isArray()){
						dataMap.put(fieldName, 
								objectMapper.readValue(jsonNodeIt, objectMapper.getTypeFactory().constructCollectionType(List.class, Map.class)));
					}else{
						dataMap.put(fieldName, objectMapper.readValue(jsonNodeIt, Map.class));
						
					}
				}
			}
			logger.debug("request bond values+++++:"+objectMapper.writeValueAsString(dataMap));
			return dataMap;
		}
}
